;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Copyright 2021 fanguangping
; 
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
; 
;     http://www.apache.org/licenses/LICENSE-2.0
; 
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

#lang racket

(require "../../racket-funny/common/constants.scm")
(require "../../racket-funny/ds/Object.scm")
(require "../../racket-funny/ds/Statement.scm")

(provide (all-defined-out))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Preparing statements of following code:
;
; {code module functions {funny-example} {math} {sqrt}}
; 
; {define function {square}:
;   {square of {x}} as
;   {{x}*{x}}}
; 
; {define function {abs}: 
;   {the absolute value of {x}} as 
;   {case
;      when {{x}>{0}} then {x},
;      when {{x}={0}} then {0},
;      when {{x}<{0}} then {-{x}}}}
; 
; {define function {ave}:
;   {the average value of {a} and {b}} as
;   {{{a}+{b}}/{2}}}
; 
; {define function {improve}:
;   {{guess} improve for {x}} as
;   {the average value of {guess} and {{x}/{guess}}}}
; 
; {define function {near}:
;   {{guess} near {x}} as
;   {{the absolute value of {{square of {guess}}-{x}}}<{0.000001}}}
; 
; {define function {sqrt-iter}:
;   {the sqrt iterator of {x} and {guess}} as
;   {if {{guess} near {x}} then {guess}, 
;    else {the sqrt iterator of {x} and {{guess} improve for {x}}}}}
; 
; {define function {sqrt}:
;   {sqrt of {x}} as
;   {the sqrt iterator of {x} and {1.0}}}
; 
; {sqrt of {2}}
; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; statement: {code module functions {funny-example} {math} {sqrt}}

(define statement-code-module
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "code")
         (CREATE-OneSymbol "module")
         (CREATE-OneSymbol "functions")
         (CREATE-OneArgument "funny-example")
         (CREATE-OneArgument "math")
         (CREATE-OneArgument "sqrt"))))

; statement: {define function {name}: {function} as {statement}}

(define statement-define-function
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "define")
         (CREATE-OneSymbol "function")
         (CREATE-OneArgument "name")
         (CREATE-OneSymbol ":")
         (CREATE-OneArgument "function")
         (CREATE-OneSymbol "as")
         (CREATE-OneArgument "statement"))))

; statement: {square of {x}}

(define statement-square
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "square")
         (CREATE-OneSymbol "of")
         (CREATE-OneArgument "x"))))

; statement: {{x} * {y} {* {z} ...}}

(define statement-multiply
  (CREATE-OneStatement
   (list (CREATE-OneArgument "x")
         (CREATE-OneSymbol "*")
         (CREATE-OneArgument "y")
         (CREATE-OneStatement
          (list (CREATE-OneSymbol "*")
                (CREATE-OneArgument "z")
                (CREATE-OneSymbol "..."))))))

; statement: {the absolute value of {x}}

(define statement-abs
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "the")
         (CREATE-OneSymbol "absolute")
         (CREATE-OneSymbol "value")
         (CREATE-OneSymbol "of")
         (CREATE-OneArgument "x"))))

; statement: {case {when {when_clause} then {then_clause}, ...}}

(define statement-case
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "case")
         (CREATE-OneStatement
          (list (CREATE-OneSymbol "when")
                (CREATE-OneArgument "when_clause")
                (CREATE-OneSymbol "then")
                (CREATE-OneArgument "then_clause")
                (CREATE-OneSymbol ",")
                (CREATE-OneSymbol "..."))))))

; statement: {{x} > {y} {> {z} ...}}

(define statement-gt
  (CREATE-OneStatement
   (list (CREATE-OneArgument "x")
         (CREATE-OneSymbol ">")
         (CREATE-OneArgument "y")
         (CREATE-OneStatement
          (list (CREATE-OneSymbol ">")
                (CREATE-OneArgument "z")
                (CREATE-OneSymbol "..."))))))

; statement: {{x} = {y} {= {z} ...}}

(define statement-eq
  (CREATE-OneStatement
   (list (CREATE-OneArgument "x")
         (CREATE-OneSymbol "=")
         (CREATE-OneArgument "y")
         (CREATE-OneStatement
          (list (CREATE-OneSymbol "=")
                (CREATE-OneArgument "z")
                (CREATE-OneSymbol "..."))))))

; statement: {{x} < {y} {< {z} ...}}

(define statement-lt
  (CREATE-OneStatement
   (list (CREATE-OneArgument "x")
         (CREATE-OneSymbol "<")
         (CREATE-OneArgument "y")
         (CREATE-OneStatement
          (list (CREATE-OneSymbol "<")
                (CREATE-OneArgument "z")
                (CREATE-OneSymbol "..."))))))

; statement: {-{x}}

(define statement-minus
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "-")
         (CREATE-OneArgument "x"))))

; statement: {the average value of {a} and {b}}

(define statement-ave
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "the")
         (CREATE-OneSymbol "average")
         (CREATE-OneSymbol "value")
         (CREATE-OneSymbol "of")
         (CREATE-OneArgument "a")
         (CREATE-OneSymbol "and")
         (CREATE-OneArgument "b"))))

; statement: {{x} + {y} {+ {z} ...}}

(define statement-add
  (CREATE-OneStatement
   (list (CREATE-OneArgument "x")
         (CREATE-OneSymbol "+")
         (CREATE-OneArgument "y")
         (CREATE-OneStatement
          (list (CREATE-OneSymbol "+")
                (CREATE-OneArgument "z")
                (CREATE-OneSymbol "..."))))))

; statement: {{guess} improve for {x}}

(define statement-improve
  (CREATE-OneStatement
   (list (CREATE-OneArgument "guess")
         (CREATE-OneSymbol "improve")
         (CREATE-OneSymbol "for")
         (CREATE-OneArgument "x"))))

; statement: {{x} / {y} {/ {z} ...}}

(define statement-divide
  (CREATE-OneStatement
   (list (CREATE-OneArgument "x")
         (CREATE-OneSymbol "/")
         (CREATE-OneArgument "y")
         (CREATE-OneStatement
          (list (CREATE-OneSymbol "/")
                (CREATE-OneArgument "z")
                (CREATE-OneSymbol "..."))))))

; statement: {{guess} near {x}}

(define statement-near
  (CREATE-OneStatement
   (list (CREATE-OneArgument "guess")
         (CREATE-OneSymbol "near")
         (CREATE-OneArgument "x"))))

; statement: {{x} - {y} {- {z} ...}}

(define statement-subtract
  (CREATE-OneStatement
   (list (CREATE-OneArgument "x")
         (CREATE-OneSymbol "-")
         (CREATE-OneArgument "y")
         (CREATE-OneStatement
          (list (CREATE-OneSymbol "-")
                (CREATE-OneArgument "z")
                (CREATE-OneSymbol "..."))))))

; statement: {the sqrt iterator of {x} and {guess}}

(define statement-sqrt-iter
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "the")
         (CREATE-OneSymbol "sqrt")
         (CREATE-OneSymbol "iterator")
         (CREATE-OneSymbol "of")
         (CREATE-OneArgument "x")
         (CREATE-OneSymbol "and")
         (CREATE-OneArgument "guess"))))

; statement: {if {if_clause} then {then_clause}, else {else_clause}}

(define statement-if
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "if")
         (CREATE-OneArgument "if_clause")
         (CREATE-OneSymbol "then")
         (CREATE-OneArgument "then_clause")
         (CREATE-OneSymbol ",")
         (CREATE-OneSymbol "else")
         (CREATE-OneArgument "else_clause"))))

; statement: {sqrt of {x}}

(define statement-sqrt
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "sqrt")
         (CREATE-OneSymbol "of")
         (CREATE-OneArgument "x"))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Preparing compute domains of following code:
;
; {code module functions {funny-example} {math} {sin}}
; {code module functions {funny-example} {math} {cos}}
; {code module functions {funny-example} {math} {tan}}
; {code module classes {funny-example} {Animal}}
; {code module classes {funny-example} {Chicken}}
; {code module classes {funny-example} {Duck}}
; {code module procedure {funny-example} {poly}}
; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define compute-domains-sin
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "code")
         (CREATE-OneSymbol "module")
         (CREATE-OneSymbol "functions")
         (CREATE-OneArgument "funny-example")
         (CREATE-OneArgument "math")
         (CREATE-OneArgument "sin"))))

(define compute-domains-cos
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "code")
         (CREATE-OneSymbol "module")
         (CREATE-OneSymbol "functions")
         (CREATE-OneArgument "funny-example")
         (CREATE-OneArgument "math")
         (CREATE-OneArgument "cos"))))

(define compute-domains-tan
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "code")
         (CREATE-OneSymbol "module")
         (CREATE-OneSymbol "functions")
         (CREATE-OneArgument "funny-example")
         (CREATE-OneArgument "math")
         (CREATE-OneArgument "tan"))))

(define compute-domains-animal
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "code")
         (CREATE-OneSymbol "module")
         (CREATE-OneSymbol "classes")
         (CREATE-OneArgument "funny-example")
         (CREATE-OneArgument "Animal"))))

(define compute-domains-chicken
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "code")
         (CREATE-OneSymbol "module")
         (CREATE-OneSymbol "classes")
         (CREATE-OneArgument "funny-example")
         (CREATE-OneArgument "Chicken"))))

(define compute-domains-duck
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "code")
         (CREATE-OneSymbol "module")
         (CREATE-OneSymbol "classes")
         (CREATE-OneArgument "funny-example")
         (CREATE-OneArgument "Duck"))))

(define compute-domains-poly
  (CREATE-OneStatement
   (list (CREATE-OneSymbol "code")
         (CREATE-OneSymbol "module")
         (CREATE-OneSymbol "procedure")
         (CREATE-OneArgument "funny-example")
         (CREATE-OneArgument "poly"))))
